// Copyright (C) 2002-2008 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h

#ifndef __SEVENT_RECEIVER_H_INCLUDED__
#define __SEVENT_RECEIVER_H_INCLUDED__


#include "../EzCore/EzEnumTypes.h"
#include "../EzCore/EzTypes.h"
#include "../EzCore/Keycodes.h"

//! Enumeration for all event types there are.
enum EEVENT_TYPE
{
	EET_GUI_EVENT = 0,
	EET_MOUSE_INPUT_EVENT,
	EET_KEY_INPUT_EVENT,
	EET_JOYSTICK_INPUT_EVENT, 
	EET_LOG_TEXT_EVENT,
	EET_USER_EVENT,
	EGUIET_FORCE_32_BIT = 0x7fffffff

};

//! Enumeration for all mouse input events
enum EMOUSE_INPUT_EVENT
{
	EMIE_LMOUSE_PRESSED_DOWN = 0,
	EMIE_RMOUSE_PRESSED_DOWN,
	EMIE_MMOUSE_PRESSED_DOWN,
	EMIE_LMOUSE_LEFT_UP,
	EMIE_RMOUSE_LEFT_UP,
	EMIE_MMOUSE_LEFT_UP,
	EMIE_MOUSE_MOVED,	
	EMIE_MOUSE_DOWN_MOVED,
	EMIE_MOUSE_WHEEL,
	EMIE_COUNT
};



//! SEvents hold information about an event. See irr::IEventReceiver for details on event handling.
struct SEvent
{
	////! Any kind of GUI event.
	//struct SGUIEvent
	//{
	//	//! IGUIElement who called the event
	//	gui::IGUIElement* Caller;

	//	//! If the event has something to do with another element, it will be held here.
	//	gui::IGUIElement* Element;

	//	//! Type of GUI Event
	//	gui::EGUI_EVENT_TYPE EventType;

	//};

	//! Any kind of mouse event.
	struct SMouseInput
	{
		//! X position of mouse cursor
		s32 X;
		//! Y position of mouse cursor
		s32 Y;
		//! mouse wheel delta, usually 1.0 or -1.0.
		/** Only valid if event was EMIE_MOUSE_WHEEL */
		f32 fWheel;

		//! Type of mouse event
		EMOUSE_INPUT_EVENT Event;
	};

	//! Any kind of keyboard event.
	struct SKeyInput
	{
		//! Character corresponding to the key (0, if not a character)
		wchar_t Char;

		//! Key which has been pressed or released
		EKEY_CODE eKey;

		//! If not true, then the key was left up
		bool bPressedDown;

		//! True if shift was also pressed
		bool bShift;

		//! True if ctrl was also pressed
		bool bControl;
	};

	//! A joystick event.
	/** Unlike other events, joystick events represent the result of polling 
	 * each connected joystick once per run() of the device. Joystick events will
	 * not be generated by default.  If joystick support is available for the 
	 * active device, _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ is defined, and 
	 * @ref IrrlichtDevice::activateJoysticks() has been called, an event of 
	 * this type will be generated once per joystick per @ref IrrlichtDevice::run() 
	 * regardless of whether the state of the joystick has actually changed. */
	struct SJoystickEvent
	{
		enum
		{
			NUMBER_OF_BUTTONS = 32,

			AXIS_X = 0, // e.g. analog stick 1 left to right
			AXIS_Y,		// e.g. analog stick 1 top to bottom
			AXIS_Z,		// e.g. throttle, or analog 2 stick 2 left to right
			AXIS_R,		// e.g. rudder, or analog 2 stick 2 top to bottom
			AXIS_U,
			AXIS_V,
			NUMBER_OF_AXES
		};

		/** A bitmap of button states.  You can use IsButtonPressed() to
		 ( check the state of each button from 0 to (NUMBER_OF_BUTTONS - 1) */
		u32 ButtonStates;

		/** For AXIS_X, AXIS_Y, AXIS_Z, AXIS_R, AXIS_U and AXIS_V
		 * Values are in the range -32768 to 32767, with 0 representing
		 * the center position.  You will receive the raw value from the 
		 * joystick, and so will usually want to implement a dead zone around 
		 * the center of the range. Axes not supported by this joystick will 
		 * always have a value of 0. On Linux, POV hats are represented as axes, 
		 * usually the last two active axis.
		 */
		s16 Axis[NUMBER_OF_AXES];

		/** The POV represents the angle of the POV hat in degrees * 100, 
		 * from 0 to 35,900.  A value of 65535 indicates that the POV hat 
		 * is centered (or not present).
		 * This value is only supported on Windows.  On Linux, the POV hat
		 * will be sent as 2 axes instead. */
		u16 POV;

		//! The ID of the joystick which generated this event.
		/** This is an internal Irrlicht index; it does not EzMap directly
		 * to any particular hardware joystick. */
		u8 Joystick;

		//! A helper function to check if a button is pressed.
		bool IsButtonPressed(u32 button) const
		{
			if(button >= (u32)NUMBER_OF_BUTTONS)
				return false;

			return (ButtonStates & (1 << button)) ? true : false;
		}
	};
 

	//! Any kind of log event.
	struct SLogEvent
	{
		u32			uiErrCode;
		const c8*	Text;
	};

	//! Any kind of user event.
	struct SUserEvent
	{
		//! Some user specified data as int
		s32 UserData1;

		//! Another user specified data as int
		s32 UserData2;
	};

	EEVENT_TYPE eEventType;
	union
	{
		//struct SGUIEvent GUIEvent;
		struct SMouseInput MouseInput;
		struct SKeyInput KeyInput;
		struct SJoystickEvent JoystickEvent;
		struct SLogEvent LogEvent;
		struct SUserEvent UserEvent;
	};

};


#endif